package com.wanmait.schedule.config;

import com.wanmait.schedule.shiro.JWTFilter;
import com.wanmait.schedule.shiro.ShiroRealm;
import net.sf.ehcache.CacheManager;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

    //过滤器工厂
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        //给ShiroFilter配置安全管理器
        factoryBean.setSecurityManager(securityManager);

        //设置自己的过滤器jwt
        Map<String, Filter> filterMap = new LinkedHashMap<>();
        filterMap.put("jwt",new JWTFilter());
        factoryBean.setFilters(filterMap);

        //配置系统受限资源
        //配置系统公共资源
        //权限配置 按着从上往下的顺序查找，一旦找到匹配的路径就不会再往下查找了
        LinkedHashMap<String, String> map = new LinkedHashMap<>();
        //请求/manage/login可以匿名用户
        map.put("/manage/login", "anon");
        map.put("/manage/teacher/teacherCenter/*", "anon");
        map.put("/student/studentCenter/*", "anon");
        map.put("/student/updatePic", "anon");
        map.put("/manage/teacher/updatePic", "anon");
        map.put("/student/studentCenterUpdatePass", "anon");
        map.put("/manage/teacher/teacherCenterUpdatePass", "anon");
        //请求/manage/及其子路径都需要登录
        map.put("/manage/**", "jwt");
        map.put("/student/**","jwt");
        map.put("/studentChange/**","jwt");

        factoryBean.setFilterChainDefinitionMap(map);

        return factoryBean;
    }

    //安全管理器
    @Bean
    public DefaultWebSecurityManager securityManager(ShiroRealm shiroRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(shiroRealm);
        return securityManager;
    }

    //安全数据源
    @Bean
    public ShiroRealm shiroRealm(EhCacheManager ehCacheManager) {
        ShiroRealm shiroRealm = new ShiroRealm();
        //shiroRealm.setAuthorizationCacheName("authorizationCache");
        shiroRealm.setCacheManager(ehCacheManager);
        return shiroRealm;
    }

//    @Bean
//    public ShiroRealm shiroRealm(){
//        return new ShiroRealm();
//    }


    //缓存管理器 net.sf.ehcache.CacheManager
    //这里可能提示找不到cacheManager没关系，注意启动类上加@EnableCaching注解启用缓存，可以在业务逻辑层使用@Cachable @CacheEvict来使用缓存
    //如果spring不使用ehache，只在shiro中使用,不用注入cacheManager,也不用set，指定配置文件
    //如果启动类或者配置类上没有加@EnableCaching注解，spring就不会创建cacheManager对象
    //Parameter 0 of method ehCacheManager in com.wanmait.jwtshiro.ShiroConfig
    // required a bean of type 'net.sf.ehcache.CacheManager' that could not be found.
    //shiro和spring都使用ehcache作为缓存
/*    @Bean
    public EhCacheManager ehCacheManager(CacheManager cacheManager){
        EhCacheManager ehCacheManager = new EhCacheManager();
        ehCacheManager.setCacheManager(cacheManager);
        //ehCacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");
        return ehCacheManager;
    }*/

    //ehcache仅仅shiro使用，spring不使用
    @Bean
    public EhCacheManager ehCacheManager(){
        EhCacheManager ehCacheManager = new EhCacheManager();
        ehCacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");
        return ehCacheManager;
    }


    /**
     *  开启shiro aop注解支持.
     *  使用代理方式;所以需要开启代码支持;
     * @param securityManager
     * @return
     */
    //启用 controller 的权限注解
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new
                AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

    // 开启代理
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator creator = new
                DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);
        return creator;
    }

}
